package com.bdk.middle.management.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bdk.middle.management.api.domain.AdminDO2;
import com.bdk.middle.management.api.query.AdminQuery2DO;
import com.bdk.middle.management.core.entity.AdminEntity;
import com.bdk.middle.management.core.entity.AdminRoleEntity;
import com.bdk.middle.management.core.entity.RoleEntity;
import com.bdk.middle.management.core.mapper.AdminMapper;
import com.bdk.middle.management.api.domain.AdminDO;
import com.bdk.middle.management.api.domain.RoleDO;
import com.bdk.middle.management.api.query.AdminQueryDO;
import com.bdk.middle.management.core.mapper.AdminRoleMapper;
import com.bdk.middle.management.core.mapper.RoleMapper;
import com.bdk.middle.management.service.AdminService;
import com.bdk.middle.management.service.RoleService;
import com.bdk.middle.common.status.ErrorCode;
import com.bdk.middle.common.domain.PageDO;
import com.bdk.middle.common.result.ResultDO;
import com.bdk.middle.common.util.BeanUtilsExtends;
import com.bdk.middle.common.util.Constant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 用户登录表 服务实现类
 * </p>
 *
 * @author Reagan
 * @since 2021-01-23
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, AdminEntity> implements AdminService {

    private Logger          logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private AdminMapper     adminMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PasswordEncoder         passwordEncoder;

    @Autowired
    private AdminRoleMapper adminRoleMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Override
    public ResultDO add(AdminDO domain) {

        ResultDO result = isUserExist(domain.getUsername());

        if(!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        AdminEntity entity = new AdminEntity();
        result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        entity.setCreateDate(Calendar.getInstance().getTime());
        entity.setModifiDate(entity.getCreateDate());
        entity.setModifier(entity.getCreator());
        entity.setPassword(passwordEncoder.encode(domain.getPassword()));

        int res = -1;
        try {
            res = adminMapper.insert(entity);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_ADD_ERROR);
            logger.debug("error code：" + ErrorCode.USER_ADD_ERROR.getCode() + " msg" + ErrorCode.USER_ADD_ERROR.getMsg());
            return result;
        }
        if(domain.getRoleIds() != null) {
            result = roleService.bindRoles(entity.getId(), domain.getRoleIds());
        }

        return result;
    }

    @Override
    public ResultDO editPassword(AdminDO domain) {

        ResultDO result = new ResultDO();

        AdminEntity entity = new AdminEntity();
        entity.setId(domain.getId());
        entity.setPassword(passwordEncoder.encode(domain.getPassword()));

        int res = -1;
        try {
            res = adminMapper.updateById(entity);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_EDIT_PASSWORD_ERROR);
            logger.debug("error code：" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getCode() + " msg" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getMsg());
            return result;
        }

        return result;
    }

    /**
     * 查询用户是否存在
     * @param username 用户名
     * @return
     */
    @Override
    public ResultDO isUserExist(String username) {

        ResultDO result = new ResultDO();

        QueryWrapper<AdminEntity> queryWrapper = new QueryWrapper<AdminEntity>();
        //修改查询用户是否存在为等于查询
        queryWrapper.lambda().eq(AdminEntity::getUsername, username).eq(AdminEntity::getIsDelete, Constant.IS_DELETE_FALSE);

        int count = 0;
        try {
            count = adminMapper.selectCount(queryWrapper);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        if(count == 1) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_NAME_IS_EXIST);
        }

        return result;
    }

    @Override
    public ResultDO edit(AdminDO domain) {

        AdminEntity entity = new AdminEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        entity.setModifiDate(Calendar.getInstance().getTime());

        int res = -1;
        try {
            res = adminMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_EDIT_ERROR);
            logger.debug("error code：" + ErrorCode.USER_EDIT_ERROR.getCode() + " msg" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getMsg());
            return result;
        }

        if(domain.getRoleIds() != null) {
            result = roleService.unbindRoles(domain.getId());
            if(!result.isSuccess()) {
                logger.debug(result.getErrorCode().getMsg());
                return result;
            }
            result = roleService.bindRoles(domain.getId(), domain.getRoleIds());
            if(!result.isSuccess()) {
                logger.debug(result.getErrorCode().getMsg());
                return result;
            }
        }

        return result;
    }



    @Override
    public ResultDO getUserByName(String username) {

        ResultDO result = new ResultDO();

        AdminEntity entity = null;

        QueryWrapper<AdminEntity> queryWrapper = new QueryWrapper<AdminEntity>();
        queryWrapper.lambda().eq(AdminEntity::getUsername, username).eq(AdminEntity::getIsDelete, Constant.IS_DELETE_FALSE);
        try {
            entity = adminMapper.selectOne(queryWrapper);
        } catch(Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        if(entity == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_DOES_NOT_EXIST);
            logger.debug("error code：" + ErrorCode.USER_DOES_NOT_EXIST.getCode() + " msg" + ErrorCode.USER_DOES_NOT_EXIST.getMsg());
            return result;
        }

        AdminDO domain = getDomain(entity);

        if(domain == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_COPY_OBJECT_ERROR);
            logger.debug("error code：" + ErrorCode.SYSTEM_COPY_OBJECT_ERROR.getCode() + " msg" + ErrorCode.SYSTEM_COPY_OBJECT_ERROR.getMsg());
            return result;
        }

        result = roleService.getRoleByUserId(domain.getId());

        if(!result.isSuccess()) {
            logger.debug(result.getErrorCode().getMsg());
            return result;
        }
        domain.setAuthorities((List<RoleDO>) result.getModel(ResultDO.FIRST_MODEL_KEY));
        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);
        return result;
    }

    @Override
    public ResultDO get(String id) {
        ResultDO result = new ResultDO();

        AdminEntity entity = null;

        try {
            entity = adminMapper.selectById(id);
        } catch(Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        AdminDO domain = getDomain(entity);

        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

        return result;
    }

    /**
     * 查询用户详情
     * @param userId 系统用户id
     * @return
     */
    @Override
    public ResultDO getDetail(String userId) {
        ResultDO result = new ResultDO();

        AdminEntity entity = null;

        try {
            entity = adminMapper.selectById(userId);
        } catch(Exception e) {

            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_GET_ERROR);
            logger.debug("error code：" + ErrorCode.USER_GET_ERROR.getCode() + " msg" + ErrorCode.USER_GET_ERROR.getMsg());
            return result;
        }

        AdminDO2 userRecord = getDomain2(entity);
        //查角色名

        String roleSetStr=roleService.getRoleStringByUserId(userRecord.getId());
        userRecord.setRoleNames(roleSetStr);

        result.setModel(ResultDO.FIRST_MODEL_KEY, userRecord);

        return result;
    }

    @Override
    public ResultDO remove(String id, String modifier) {

        ResultDO result = new ResultDO();

        AdminEntity entity = new AdminEntity();

        entity.setModifiDate(Calendar.getInstance().getTime());
        entity.setModifier(modifier);
        entity.setId(id);
        entity.setIsDelete(Constant.IS_DELETE);

        int res = -1;
        try {
            res = adminMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_DELETE_ERROR);
            logger.debug("error code：" + ErrorCode.USER_DELETE_ERROR.getCode() + " msg" + ErrorCode.USER_DELETE_ERROR.getMsg());
            return result;
        }

        return result;
    }

    @Override
    public ResultDO find(AdminQueryDO query) {

        AdminEntity entity = new AdminEntity();

        ResultDO result = BeanUtilsExtends.copy(entity,query);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        QueryWrapper<AdminEntity> wrapper = new QueryWrapper<AdminEntity>(entity);

        Page<AdminEntity> page = new Page<>(query.getCurrentPage(),query.getPageSize());
        IPage<AdminEntity> iPage = null;
        try {
            iPage = adminMapper.selectPage(page, wrapper);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        List<AdminDO> doList = getDomainList(iPage.getRecords());

        PageDO<AdminDO> pageDO = new PageDO<>();

        pageDO.setCurrentPage(iPage.getCurrent());
        pageDO.setPageCount(iPage.getPages());
        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(iPage.getTotal());
        pageDO.setData(doList);

        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
        return result;
    }


    /**
     * 查找用户列表
     * @param query
     * @return
     */
    @Override
    public ResultDO find2(AdminQueryDO query) {

        AdminEntity entity = new AdminEntity();

        ResultDO result = BeanUtilsExtends.copy(entity,query);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        QueryWrapper<AdminEntity> wrapper = new QueryWrapper<AdminEntity>(entity);
        wrapper.eq("is_delete",1);
        Page<AdminEntity> page = new Page<>(query.getCurrentPage(),query.getPageSize());
        IPage<AdminEntity> iPage = null;
        try {
            iPage = adminMapper.selectPage(page, wrapper);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_GET_ERROR);
            logger.debug("error code：" + ErrorCode.USER_GET_ERROR.getCode() + " msg" + ErrorCode.USER_GET_ERROR.getMsg());
            return result;
        }

        List<AdminDO2> doList = getDomainList2(iPage.getRecords());
        //查角色名
        for(AdminDO2 u:doList){
            String roleSetStr=roleService.getRoleNamesByUserId(u.getId());
            u.setRoleNames(roleSetStr);

        }
        PageDO<AdminDO2> pageDO = new PageDO<>();

        pageDO.setCurrentPage(iPage.getCurrent());
        pageDO.setPageCount(iPage.getPages());
        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(iPage.getTotal());
        pageDO.setData(doList);

        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
        return result;
    }

    /**
     * 模糊查找用户列表
     * @param query
     * @return
     */
    @Override
    public ResultDO findByLike(AdminQueryDO query) {

        ResultDO result=new ResultDO();
        QueryWrapper<AdminEntity> wrapper = new QueryWrapper<AdminEntity>();
        wrapper.eq("is_delete",1);
        wrapper.like("username", query.getUsername());
        Page<AdminEntity> page = new Page<>(query.getCurrentPage(),query.getPageSize());
        IPage<AdminEntity> iPage = null;
        try {
            iPage = adminMapper.selectPage(page, wrapper);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_GET_ERROR);
            logger.debug("error code：" + ErrorCode.USER_GET_ERROR.getCode() + " msg" + ErrorCode.USER_GET_ERROR.getMsg());
            return result;
        }

        List<AdminDO2> doList = getDomainList2(iPage.getRecords());
        //查角色名
        for(AdminDO2 u:doList){
            String roleSetStr=roleService.getRoleNamesByUserId(u.getId());
            u.setRoleNames(roleSetStr);
        }
        PageDO<AdminDO2> pageDO = new PageDO<>();

        pageDO.setCurrentPage(iPage.getCurrent());
        pageDO.setPageCount(iPage.getPages());
        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(iPage.getTotal());
        pageDO.setData(doList);

        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
        return result;
    }

    private AdminDO getDomain(AdminEntity entity) {
        ResultDO result = new ResultDO();
        //判断源对象是否为空，为空就返回 空，不为空就进行下面的代码
        if(entity == null) return null;
        AdminDO domain = new AdminDO();

        if(!result.isSuccess()) {
            return null;
        }
        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        //判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
        return domain;
    }


    private  List<AdminDO> getDomainList(List<AdminEntity> list) {
        //创建一个名为dolist的房源do类型的 list集合
        List<AdminDO> doList = new ArrayList<>();

        //判断传入的list的集合的size是否大于0
        if(list.size() > 0) {
            //大于0是，遍历list，创建do类型的对象 调用getdomain方法
            for(AdminEntity entity : list) {

                AdminDO domain = this.getDomain(entity);

                //判断得到的domain 是否为空 不为空 就往dolist集合里面添加domian 为空就返回空
                if(domain == null) {
                    return null;
                }
                doList.add(domain);
            }
        } else {
            return null;
        }
        return doList;
    }

    private AdminDO2 getDomain2(AdminEntity entity) {
        ResultDO result = new ResultDO();
        //判断源对象是否为空，为空就返回 空，不为空就进行下面的代码
        if(entity == null) return null;
        AdminDO2 domain = new AdminDO2();

        if(!result.isSuccess()) {
            return null;
        }
        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        //判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
        return domain;
    }


    private  List<AdminDO2> getDomainList2(List<AdminEntity> list) {
        //创建一个名为dolist的房源do类型的 list集合
        List<AdminDO2> doList = new ArrayList<>();

        //判断传入的list的集合的size是否大于0
        if(list.size() > 0) {
            //大于0是，遍历list，创建do类型的对象 调用getdomain方法
            for(AdminEntity entity : list) {

                AdminDO2 domain = this.getDomain2(entity);

                //判断得到的domain 是否为空 不为空 就往dolist集合里面添加domian 为空就返回空
                if(domain == null) {
                    return null;
                }
                doList.add(domain);
            }
        } else {
            return null;
        }
        return doList;
    }


    /**
     * 更新系统用户信息
     * @param domain 用户DO
     * @return
     */
    @Override
    @Transactional
    public ResultDO update(AdminQuery2DO domain) {
        ResultDO result=new ResultDO();

        QueryWrapper<AdminEntity> qWrapper = new QueryWrapper<>();
        qWrapper.eq("username",domain.getUsername());
        AdminEntity adminRecord=adminMapper.selectOne(qWrapper);
        if(adminRecord==null){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_IS_NO_EXIST);
            return result;
        }
        //设置需要更新的字段
        if(domain.getPassword()!=null && domain.getPassword().length()>=3){
           adminRecord.setPassword(passwordEncoder.encode(domain.getPassword()));
        }
        if(domain.getStatus()!=null){
            adminRecord.setStatus(domain.getStatus());
        }
        adminMapper.update(adminRecord,qWrapper);
        //更新角色
        if(domain.getRoleId()!=null && domain.getRoleId().length()>3){
             //检查角色是否存在
            QueryWrapper<RoleEntity> roleWrapper = new QueryWrapper<>();
            roleWrapper.eq("id",domain.getRoleId());
            int count = 0;
            count = roleMapper.selectCount(roleWrapper);
            if(count<1){
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.ROLE_GET_ERROR);
            }
            //用户拥有角色了
            QueryWrapper<AdminRoleEntity> adminRoleWrapper = new QueryWrapper<>();
            adminRoleWrapper.eq("user_id",adminRecord.getId());
            //adminRoleWrapper.eq("role_id",domain.getRoleId());
            List<AdminRoleEntity> adminRoleRecords=adminRoleMapper.selectList(adminRoleWrapper);
            if(adminRoleRecords!=null || !adminRoleRecords.isEmpty()){
                  //删除之前的关联
                  adminRoleMapper.delete(adminRoleWrapper);
            }
                  //修改用户角色关联
//                  UpdateWrapper<AdminRoleEntity> updateWrapper = new UpdateWrapper<>();
//                  updateWrapper.eq("user_id",adminRecord.getId())
//                               .set("role_id",domain.getRoleId());
//
//                  adminRoleMapper.update(null, updateWrapper);
                   // throw new CustomException(ErrorCode.ROLE_ALREADY_OWN.getCode(),ErrorCode.ROLE_ALREADY_OWN.getMsg());
                    // result.setSuccess(false);
                    // result.setErrorCode(ErrorCode.ROLE_ALREADY_OWN);


            //新增用户角色关联
            AdminRoleEntity insertRecord=new AdminRoleEntity();
            insertRecord.setUserId(adminRecord.getId());
            insertRecord.setRoleId(domain.getRoleId());
            adminRoleMapper.insert(insertRecord);

        }
        return result;
    }

    /**
     * 根据系统用户名,返回用户对象
     * @param userName
     * @return
     */
    public AdminEntity getAdminUser(String userName) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("username",userName);
        AdminEntity adminEntity=adminMapper.selectOne(queryWrapper);
        return adminEntity;
    }
}
